package com.yh.service;

import com.yh.entity.*;
import com.yh.vo.CustomPageAndNavigate;
import com.yh.vo.CinemaVO;
import com.yh.vo.HallVO;
import com.yh.vo.ScheduleVO;

import java.util.Date;
import java.util.List;

/**
 * @author yuhuan
 * @date 2022/01/13
 */
public interface CinemaService {
    /**
     * 查询所有的影院品牌
     *
     * @return 返回查询的所有结果集
     */
    public List<Brand> findCinemaBrandAll();

    /**
     * 查询所有的影院信息不分页
     *
     * @return 返回所有的影院信息
     */
    public List<CinemaVO> findCinemaAll();

    /**
     * 查询所有的影院信息并分页
     *
     * @param pageNum  当前页
     * @param pageSize 页大小
     * @return 返回自定义的分页信息实体
     */
    public CustomPageAndNavigate findCinemaAllToPage(Integer pageNum, Integer pageSize);

    /**
     * 按影片ID、品牌和时间表搜索电影院并分页
     *
     * @param cinemaVO 查询条件（包括影片ID、品牌、时间和分页条件）
     * @return 返回分页后的查询结果集
     */
    public CustomPageAndNavigate seachCinemaByMovieIdAndBrandAndSchedule(CinemaVO cinemaVO);

    /**
     * 根据影院的ID查询影院的详细信息（包括影院的基本信息、影院提供所有服务和影院播放的所有影片）
     *
     * @param cinemaId 影院的ID
     * @return 返回查询到的影院详情；可能为空
     */
    public CinemaVO findCinemaDetailById(int cinemaId);

    /**
     * 根据影片ID查询所有的影院
     *
     * @param movieId 影片ID，用于筛选影院信息
     * @return 返回查询到的所有详情模型，并不包含详情信息（仅拷贝基本信息+影厅数量计算）
     */
    public List<CinemaVO> findCinemaByMovieId(Integer movieId);

    /**
     * 新增上映影片；合并新的影片信息到上映影片列表，将自动忽略原上映影片列表中已经存在的影片和已经删除的影片
     *
     * @param vo 包含已经上映的影片列表和新增的影片ID列表
     * @return 合并后的新影片列表
     */
    public List<Movie> addMovieOnCinemaDetail(CinemaVO vo);

    /**
     * 移除影院已经上映的影片。主要是检查当前影院移除的影片是否已经创建了放映计划；如果已经创
     * 建计划，则禁止移除。匹配到不存的影院ID时，则忽略该检查计划，直接移除影片信息；这种情况
     * 一般是发生在新增影院信息时。
     *
     * @param vo 等待移除的信息（包括影片ID，影院ID和影院上映的影片列表）
     * @return 如果已经生成过放映计划将直接返回原影片列表；否则将返回移除后的影片列表
     */
    public List<Movie> deleteMovieOnCinemaDetail(CinemaVO vo);

    /**
     * 新增影片
     *
     * @param vo 新增的影片基本信息
     * @return 返回添加成功的总记录数
     */
    public int addCinema(CinemaVO vo);

    /**
     * 修改影院信息
     *
     * @param vo 修改的影院基本信息
     * @return 返回修改成功的总记录数
     */
    public int updateCinema(CinemaVO vo);

    /**
     * 查询所有的影厅信息并分页
     *
     * @param pageNum  当前页
     * @param pageSize 页大小
     * @return 返回自定义的分页信息实体
     */
    public CustomPageAndNavigate findHallAll(Integer pageNum, Integer pageSize);

    /**
     * 根据影院查找所有的影厅
     *
     * @param cinemaId 影院ID
     * @return 所有查找到的影厅基本信息
     */
    public List<Hall> findHallByCinemaId(Integer cinemaId);

    /**
     * 根据ID精确查询影厅详情
     *
     * @param hallId 影厅的ID
     * @return 返回查询到的影厅的详情（包括基本信息、影厅类型和影厅的布局）
     */
    public HallVO findHallDetailById(int hallId);

    /**
     * 添加影厅
     *
     * @param vo 需要添加到数据库的影厅信息（包含了影厅的布局）
     * @return 返回插入成功的总记录数
     */
    public int addHall(HallVO vo);

    /**
     * 修改影厅信息
     *
     * @param vo 修改的影厅信息
     * @return 返回修改成功的总记录数
     */
    public int updateHall(HallVO vo);

    /**
     * 根据影厅的ID移除关联的所有布局信息
     *
     * @param hallId 需要删除布局信息的影厅ID
     * @return 返回删除的响应状态
     */
    public int removeLayoutByHallId(Integer hallId);

    /**
     * 查询所有的影厅类型
     *
     * @return 返回所有的查询结果
     */
    public List<HallType> findHallTypeAll();

    /**
     * 查询所有的影厅放映计划并分页
     *
     * @param pageNum   当前页
     * @param pageSize  页大小
     * @param condition 查询条件（可以设置为上映或者下架，未设置时会查询所有数据）
     * @return 返回自定义的分页信息实体
     */
    public CustomPageAndNavigate findScheduleAll(Integer pageNum, Integer pageSize, String condition);

    /**
     * 根据场次ID查询场次详情
     *
     * @param scheduleId 场次ID（即：日程ID）
     * @return 返回查询的计划详情（包括：基本信息、归属的影院、归属的影厅、影厅的类型、影片的版本和座位的售出情况）
     */
    public ScheduleVO findScheduleDetailById(int scheduleId);

    /**
     * 根据影片ID、影院ID和播放的开始日期查询当天的所有日程详情
     *
     * @param movieId  影片的ID
     * @param cinemaId 影院的ID
     * @param dateSign 选中的影片播放时间
     * @return 返回查询到的所有结果集
     */
    public List<ScheduleVO> findScheduleDetailsByMovieIdAndCinemaIdAndStartDate(int movieId, int cinemaId, int dateSign);

    /**
     * 根据影片的名称搜索日程并分页
     *
     * @param pageNum   当前页
     * @param pageSize  页大小
     * @param condition 搜索条件
     * @param keyword   搜索的关键字
     * @return 自定义的分页信息实体
     */
    public CustomPageAndNavigate searchScheduleByMovieNameToPage(Integer pageNum, Integer pageSize, String keyword, String condition);

    /**
     * 添加日程
     *
     * @param vo 需要添加到数据库的日程信息
     * @return 返回数据更新的状态响应标识
     */
    public int addSchedule(ScheduleVO vo);

    /**
     * 取消影片的放映计划（仅限未创建订单的计划）。如果当前计划已经创建了订单，则不允许取消，另外，该
     * 方法只是在逻辑上将数据标记为删除并不做真实的物理删除
     *
     * @param scheduleId 需要取消的日程
     * @return 返回删除的结果
     */
    public boolean deleteSchedule(Integer scheduleId);

    /**
     * 更新计划表(通过定时任务每天更新指定影片的播放计划)；一部影片在一个影院中有且仅生成一条放映计划。可以理解为同
     * 一天的同一个影院只能在一个影厅的某一段时间放映该影片（且仅限一场）。你也可以指定一个任意的时间来更新
     *
     * @param movieIds 要更新计划的影片ID集
     * @param planTime 指定影片的放映计划（通常是设置为当前时间;如果不是设置为当前时间，那么这个时间的设置最好不
     *                 要超过'switchDateSignToDate'方法的解析范围。因为超过这个范围将导致本方法无法对当期计
     *                 划进行检查，从而导致生成重复的计划。这个最大范围默认是支持距离今天的第五天，详见常量中相对
     *                 今天偏移量的最大值）
     */
    public void updateScheduleByDateAndMovieId(List<Integer> movieIds, Date planTime);

    /**
     * 删除旧的的影片放映计划（规定放映计划在30天之前的为旧数据）
     *
     * @return 返回删除的总记录数
     */
    public int deleteOldSchedule();
}
